/*
 * Copyright 2016-2019 yoara
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yhao.infra.web.common.session;

import org.springframework.core.env.Environment;
import yhao.infra.common.ContextHolder;
import yhao.infra.common.cache.YhaoCache;
import yhao.infra.common.constants.InfraCacheKey;
import yhao.infra.common.spring.SpringBeanPicker;
import yhao.infra.web.ConfigFactory;

import java.util.HashMap;
import java.util.Map;

import static yhao.infra.common.ConfigFactory.COMMON_CACHE_BEAN_NAME;

/**
 * 缓存操作service
 *
 * @author yoara
 */
public class SessionService {
    private static SessionService instance = null;
    private static Object lock = new Object();
    private static int EXPIRE_TIME = 60*30;// 1800秒
    private YhaoCache yhaoCache;

    public static SessionService getInstance() {
        if (instance == null) {
            synchronized (lock) {
                if (instance == null) {
                    instance = new SessionService();
                }
            }
        }
        return instance;
    }

    private SessionService() {
        yhaoCache = SpringBeanPicker.getApplicationContext().getBean(COMMON_CACHE_BEAN_NAME, YhaoCache.class);
        Environment env = SpringBeanPicker.getApplicationContext().getBean(Environment.class);
        Integer expireTime = env.getProperty(ConfigFactory.REDIS_SESSION_EXPIRE_TIME,Integer.class);
        if(expireTime!=null){
            EXPIRE_TIME = expireTime;
        }
    }

    public Map<String, Object> getSession(String id) {
        Map<String, Object> session = null;
        if (session == null) {
            session = (Map<String, Object>) yhaoCache.get(InfraCacheKey.SESSION, id);
        }
        if (session == null) {
            session = new HashMap<>();
            saveSession(id, session);
        }
        return session;
    }

    public void saveSession(String id, Map<String, Object> session) {
        int expireTime = pickExpireTime();
        yhaoCache.put(InfraCacheKey.SESSION, id, session, expireTime);
    }

    private int pickExpireTime() {
        Object expireAppTime = ContextHolder.getContextData(SessionExpireKey.class);
        if(expireAppTime!=null){
            return (int) expireAppTime;
        }
        return EXPIRE_TIME;
    }

    public void removeSession(String id) {
        yhaoCache.remove(InfraCacheKey.SESSION, id);
    }

    /**
     * @param sessionId
     */
    public void expireSession(String sessionId) {
        int expireTime = pickExpireTime();
        yhaoCache.expire(InfraCacheKey.SESSION, sessionId, expireTime);
    }

    public enum SessionExpireKey implements ContextHolder.ContextKey {}
}
